target_python.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import sys
  2. from pip._internal.utils.compatibility_tags import (
  3. get_supported,
  4. version_info_to_nodot,
  5. )
  6. from pip._internal.utils.misc import normalize_version_info
  7. from pip._internal.utils.typing import MYPY_CHECK_RUNNING
  8. if MYPY_CHECK_RUNNING:
  9. from typing import List, Optional, Tuple
  10. from pip._vendor.packaging.tags import Tag
  11. class TargetPython(object):
  12. """
  13. Encapsulates the properties of a Python interpreter one is targeting
  14. for a package install, download, etc.
  15. """
  16. __slots__ = [
  17. "_given_py_version_info",
  18. "abi",
  19. "implementation",
  20. "platform",
  21. "py_version",
  22. "py_version_info",
  23. "_valid_tags",
  24. ]
  25. def __init__(
  26. self,
  27. platform=None, # type: Optional[str]
  28. py_version_info=None, # type: Optional[Tuple[int, ...]]
  29. abi=None, # type: Optional[str]
  30. implementation=None, # type: Optional[str]
  31. ):
  32. # type: (...) -> None
  33. """
  34. :param platform: A string or None. If None, searches for packages
  35. that are supported by the current system. Otherwise, will find
  36. packages that can be built on the platform passed in. These
  37. packages will only be downloaded for distribution: they will
  38. not be built locally.
  39. :param py_version_info: An optional tuple of ints representing the
  40. Python version information to use (e.g. `sys.version_info[:3]`).
  41. This can have length 1, 2, or 3 when provided.
  42. :param abi: A string or None. This is passed to compatibility_tags.py's
  43. get_supported() function as is.
  44. :param implementation: A string or None. This is passed to
  45. compatibility_tags.py's get_supported() function as is.
  46. """
  47. # Store the given py_version_info for when we call get_supported().
  48. self._given_py_version_info = py_version_info
  49. if py_version_info is None:
  50. py_version_info = sys.version_info[:3]
  51. else:
  52. py_version_info = normalize_version_info(py_version_info)
  53. py_version = '.'.join(map(str, py_version_info[:2]))
  54. self.abi = abi
  55. self.implementation = implementation
  56. self.platform = platform
  57. self.py_version = py_version
  58. self.py_version_info = py_version_info
  59. # This is used to cache the return value of get_tags().
  60. self._valid_tags = None # type: Optional[List[Tag]]
  61. def format_given(self):
  62. # type: () -> str
  63. """
  64. Format the given, non-None attributes for display.
  65. """
  66. display_version = None
  67. if self._given_py_version_info is not None:
  68. display_version = '.'.join(
  69. str(part) for part in self._given_py_version_info
  70. )
  71. key_values = [
  72. ('platform', self.platform),
  73. ('version_info', display_version),
  74. ('abi', self.abi),
  75. ('implementation', self.implementation),
  76. ]
  77. return ' '.join(
  78. '{}={!r}'.format(key, value) for key, value in key_values
  79. if value is not None
  80. )
  81. def get_tags(self):
  82. # type: () -> List[Tag]
  83. """
  84. Return the supported PEP 425 tags to check wheel candidates against.
  85. The tags are returned in order of preference (most preferred first).
  86. """
  87. if self._valid_tags is None:
  88. # Pass versions=None if no py_version_info was given since
  89. # versions=None uses special default logic.
  90. py_version_info = self._given_py_version_info
  91. if py_version_info is None:
  92. version = None
  93. else:
  94. version = version_info_to_nodot(py_version_info)
  95. tags = get_supported(
  96. version=version,
  97. platform=self.platform,
  98. abi=self.abi,
  99. impl=self.implementation,
  100. )
  101. self._valid_tags = tags
  102. return self._valid_tags